package qc.module.cms.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.module.cms.dto.category.CategoryDeptDto;
import qc.module.cms.dto.category.CategoryDeptSetDto;
import qc.module.cms.entity.CategoryDept;
import qc.module.cms.repository.CategoryDeptRepository;
import qc.module.platform.dto.dept.DeptSimpleDto;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * CategoryDeptService
 *
 * @author QuCheng Tech
 * @since 2023/5/30
 */
@Service
public class CategoryDeptService {

    private CategoryDeptRepository categoryDeptRepository;

    @Autowired
    public void setCategoryDeptRepository(CategoryDeptRepository categoryDeptRepository) {
        this.categoryDeptRepository = categoryDeptRepository;
    }

    /**
     * 获取所有的栏目与部门关联关系
     *
     * @return 栏目与部门关联关系
     * @author QuCheng Tech
     * @since 2023/5/26
     */
    public List<CategoryDept> getAllCategoryDept() {
        LambdaQueryWrapper<CategoryDept> wrapper = new LambdaQueryWrapper<>();
        //排序
        wrapper.orderByAsc(CategoryDept::getCid);

        //查询数据
        return categoryDeptRepository.selectList(wrapper);
    }

    /**
     * 获取指定栏目关联的部门ID集合
     *
     * @param categoryId 栏目ID
     * @return 栏目与部门关联关系
     * @author QuCheng Tech
     * @since 2023/5/26
     */
    public List<Integer> getDeptIdsByCategoryId(int categoryId) {
        LambdaQueryWrapper<CategoryDept> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(CategoryDept::getDid);
        wrapper.eq(CategoryDept::getCid, categoryId);

        //查询数据
        List<CategoryDept> ens = categoryDeptRepository.selectList(wrapper);
        if (ens != null && ens.size() > 0x0) {
            return ens.stream().map(CategoryDept::getDid).collect(Collectors.toList());
        }

        return null;
    }

    /**
     * 根据传入的用户所在部门ID集合，得到所有有效的栏目ID集合
     *
     * @param allDeptIds 用户所在的部门ID集合
     * @return 有效的栏目ID集合
     * @author QuCheng Tech
     * @since 2023/5/30
     */
    public List<Integer> getValidCategoryIds(List<Integer> allDeptIds) throws QCPromptException {
        //文章均需要根据用户所在部门进行筛选过滤，如果用户所在部门信息为空需要进行提示
        if (allDeptIds == null || allDeptIds.size() < 0x1)
            throw new QCPromptException("当前用户没有设置所在部门信息");
        //从所有栏目与部门关联信息中与用户所在部门进行交集筛选过滤
        List<CategoryDept> allCategoryDepts = getAllCategoryDept();
        if (allCategoryDepts == null || allCategoryDepts.size() < 0x1)
            throw new QCPromptException("无任何有效的栏目与部门关联信息");

        List<Integer> filterCategoryIds = new ArrayList<>();
        for (CategoryDept cd : allCategoryDepts) {
            //如果传入的用户部门中包含栏目与部门关联关系，查询的栏目ID中包含该栏目
            if (allDeptIds.contains(cd.getDid()))
                filterCategoryIds.add(cd.getCid());
        }
        if (filterCategoryIds == null || filterCategoryIds.size() < 0x1)
            throw new QCPromptException("当前用户无任何有效的栏目信息");
        //传入的id进行去重处理
        List<Integer> collect = filterCategoryIds.stream().distinct().collect(Collectors.toList());
        return collect;
    }

    public List<CategoryDeptDto> getDepts(List<Integer> categoryIds, List<DeptSimpleDto> depts) throws QCPromptException {
        if (categoryIds == null || categoryIds.size() < 0x1)
            throw new QCPromptException("指定的栏目信息不能为空");
        if (depts == null || depts.size() < 0x1)
            throw new QCPromptException("部门信息不能为空");

        //遍历栏目ID，获取每个栏目关联的部门取交集
        List<Integer> intersectDeptIds = getDeptIdsByCategoryId(categoryIds.get(0x0));
        for (Integer categoryId : categoryIds) {
            //如果已取交集的结果为空，不需要再获取后面的栏目关联的部门
            if (intersectDeptIds == null || intersectDeptIds.size() < 0x1)
                break;
            List<Integer> categoryDeptIds = getDeptIdsByCategoryId(categoryId);
            //如果当前栏目获取的关联部门集合为空，不需要取交集和遍历后面的
            if (categoryDeptIds == null || categoryDeptIds.size() < 0x1) {
                intersectDeptIds = null;
                break;
            }
            //取交集
            intersectDeptIds = intersectDeptIds.stream().filter(categoryDeptIds::contains).collect(Collectors.toList());
        }
        List<CategoryDeptDto> result = new ArrayList<>();
        for (DeptSimpleDto dept : depts) {
            boolean related = false;
            if (intersectDeptIds != null && intersectDeptIds.size() > 0x0) {
                if (intersectDeptIds.contains(dept.getId())) {
                    related = true;
                }
            }
            CategoryDeptDto dto = new CategoryDeptDto();
            dto.setDept(dept);
            dto.setChecked(related);
            result.add(dto);
        }

        return result;
    }

    /**
     * 设置栏目与部门关联关系，可一次设置多个栏目
     *
     * @param dto 关联关系
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/27
     */
    public String setDepts(CategoryDeptSetDto dto) {
        //以栏目为基准进行设置，即对传入的所有栏目均设置为相同的部门关联关系
        if (dto == null)
            return QCUnifyReturnValue.Warn("设置的信息不能为空");
        if (dto.getCids() == null || dto.getCids().length < 0x1)
            return QCUnifyReturnValue.Warn("设置的栏目信息不能为空");

        //验证栏目ID是否存在，部门ID也可以增加验证--避免出现无效数据
        //此处不判断，判断需要调用CategoryService，存在循环引用问题
        //for (int cid : dto.getCids()) {
        //    if (!hasIdExist(cid))
        //        return QCUnifyReturnValue.Warn("设置ID为" + cid + "的栏目不存在");
        //}

        //遍历栏目，先删除栏目的关联关系，再添加
        for (int cid : dto.getCids()) {
            deleteDeptsByCategoryId(cid);

            if (dto.getDids() != null && dto.getDids().length > 0x0) {
                for (int did : dto.getDids()) {
                    String addResult = addCategoryDept(cid, did);
                    if (!StringUtils.isBlank(addResult))
                        return addResult;
                }
            }
        }

        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除指定栏目ID的栏目与部门关联关系
     *
     * @param categoryId 栏目ID
     * @author 成功返回null
     * @since 2023/5/27
     */
    public void deleteDeptsByCategoryId(int categoryId) {
        LambdaUpdateWrapper<CategoryDept> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(CategoryDept::getCid, categoryId);

        categoryDeptRepository.delete(wrapper);
    }

    /**
     * 新增栏目与部门关联关系
     *
     * @param categoryId 栏目ID
     * @param deptId     部门ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/30
     */
    public String addCategoryDept(int categoryId, int deptId) {
        CategoryDept addEn = new CategoryDept();
        addEn.setCid(categoryId);
        addEn.setDid(deptId);

        categoryDeptRepository.insert(addEn);

        return QCUnifyReturnValue.Success();
    }
}
